// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Ray_3.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Ray_3.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Ray_3_doc[]=
{
"An object r of the data type Ray_3 is a directed straight ray in the three-dimensional Euclidean space. It starts in a point called the source of r and goes to infinity.\n"\
"for more details go to: http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Ray_3.html",
"r = Ray_3(Point_3 p,Point_3 q)\nintroduces a ray with source p and passing through point q.\n"\
"r = Ray_3(Point_3 p,Direction_3 d)\nintroduces a ray starting at source p with direction d.\n"\
"r = Ray_3(Point_3 p,Vector_3 v)\nintroduces a ray r starting at source p with the direction of v.\n"\
"r = Ray_3(Point_3 p,line_3 l)\nintroduces a ray r starting at source p with the same direction as l.\n",

"source(self) -> Point_3\nreturns the source of r\n",

"point(self,i) -> Point_3\nreturns a point on r. point(0) is the source, point(i), with i>0, is different from the source.\nPrecondition: i>=0.\n",

"is_degenerate(self) -> bool\nray r is degenerate, if the source and the second defining point fall together (that is if the direction is degenerate).\n",

"direction(self) -> Direction_3\nreturns the direction of r.\n",

"to_vector(self) -> Vector_3\nreturns a vector giving the direction of r\n",

"has_on(self,Point_3 p) -> bool\nA point is on r, iff it is equal to the source of r, or if it is in the interior of r\n",

"", // "collinear_has_on(self,Point_3 p) -> bool\nchecks if point p is on r.\nThis function is faster than function has_on() if the precondition checking is disabled.\nPrecondition: p is on the supporting line of r.\n",

"opposite(self) -> Ray_3\nreturns the ray with the same source and the opposite direction.\n",

"supporting_line(self) -> line_2\nreturns the line supporting r which has the same direction.\n",

"transform(Aff_transformation_2 t) -> Ray_3\nreturns the ray obtained by applying t on the source and on the direction of r.\n"
};

template<class Ray_3>
boost::python::str py_repr_Ray_3(const Ray_3& r )
{
	using namespace boost::python;
	return str("Ray_3("+ str(r.source()) +","+ str(r.direction()) +")" );
}

template <class kernel > 
void Py_Ray_3()
{
	typedef typename kernel::Point_3 						Point_3;
 	typedef typename kernel::Vector_3 						Vector_3;
 	typedef typename kernel::Direction_3 						Direction_3;
 	typedef typename kernel::Line_3 						Line_3;
  	typedef typename kernel::Ray_3 						        Ray_3;

	using namespace boost::python;

        class_< Ray_3 >("Ray_3", Ray_3_doc[0], init<>())
        .def(init< const Ray_3& >(Ray_3_doc[1]))
        .def(init< const Point_3&, const Point_3& >())
        .def(init< const Point_3&, const Vector_3& >())
        .def(init< const Point_3&, const Direction_3& >())
        .def(init< const Point_3&, const Line_3& >())
        .def("source", &Ray_3::source, BEF_33(by_cref, by_copy)(), Ray_3_doc[2])
        .def("point", &Ray_3::point, Ray_3_doc[3])
        .def("is_degenerate", &Ray_3::is_degenerate, Ray_3_doc[4])
        .def("direction", &Ray_3::direction, Ray_3_doc[5])
        .def("to_vector", &Ray_3::to_vector, Ray_3_doc[6])
        .def("has_on", &Ray_3::has_on, Ray_3_doc[7])
        // .def("collinear_has_on", &Ray_3::collinear_has_on, Ray_3_doc[8]) // does not exist in CGAL 3.3 and was never documented in 3.x
        .def("opposite", &Ray_3::opposite, Ray_3_doc[9])
        .def("supporting_line", &Ray_3::supporting_line, Ray_3_doc[10])
        .def("transform", &Ray_3::transform, Ray_3_doc[11])
 	.def("__repr__", &py_repr_Ray_3<Ray_3>)

        .def("start", &Ray_3::start, BEF_33(by_cref, by_copy)())
        .def("second_point", &Ray_3::second_point, BEF_33(by_cref, by_copy)())
        .def( self == self )
        .def( self != self )
    ;
}


void export_Ray_3()
{
	Py_Ray_3<K>();
}
